﻿/*
   Copyright 2011 Softisis

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/

using System;
using System.Collections.Generic;

namespace FOM.Interfaces
{
    /// <summary>
    /// This class contains usefull infos given to the converter and/or condition implementation.
    /// </summary>
    /// <remarks>Copyright Softisis 2011 (France)</remarks>
    public class MappingContext
    {

        public MappingContext
        (
            IConverter converter,
            ICondition condition,
            bool isnewinstance,
            bool isnewinstanceUseRef,
            bool convertBeforeTest,
            Type typeDefSrc,
            Type typeDefDst,
            object objectSource,
            object objectDest,
            object objectReplacedInDest,
            IPathLink mapPathLink,
            List<IPathLink> excludedNodes,
            IManager mapperManager,
            object topSourceObject,
            object topTargetObject,
            IDictionary<object, object> objectsCache
        )
        {
            Converter = converter;
            Condition = condition;
            IsNewInstance = isnewinstance;
            IsNewinstanceUseRef = isnewinstanceUseRef;
            ConvertBeforeTest = convertBeforeTest;
            Tsrc = typeDefSrc;
            Tdst = typeDefDst;
            ObjectSrc = objectSource;
            ObjectDst = objectDest;
            ReplacedDstObject = objectReplacedInDest;
            PathLink = mapPathLink;
            ExcludedNodes = excludedNodes;
            Manager = mapperManager;
            TopSourceObject = topSourceObject;
            TopTargetObject = topTargetObject;
            ObjectsCache = objectsCache;
        }

        /// <summary>
        /// Not null if a converter has been defined on this node.
        /// </summary>
        public IConverter Converter { get; internal set; }

        /// <summary>
        /// Not null if a mapping condition has been set.
        /// </summary>
        public ICondition Condition { get; internal set; }

        /// <summary>
        /// Say if the target object has been marked as newInstance()
        /// </summary>
        public bool IsNewInstance { get; internal set; }


        /// <summary>
        /// If true, it means the the source prop is cached in cache dictionnary
        /// </summary>
        public bool IsNewinstanceUseRef { get; internal set; }

        /// <summary>
        /// If true, this means that the engine will call the converter (if defined)
        /// before calling the mapping condition (if defined).
        /// This may affects ObjectDst according to the conversion treatment.
        /// </summary>
        public bool ConvertBeforeTest { get; internal set; }

        /// <summary>
        /// Type (expected) of source object.
        /// </summary>
        public Type Tsrc { get; internal set; }

        /// <summary>
        /// Type (expected) of target object.
        /// </summary>
        public Type Tdst { get; internal set; }

        /// <summary>
        /// Source object
        /// </summary>
        public object ObjectSrc { get; internal set; }

        /// <summary>
        /// target object
        /// </summary>
        public object ObjectDst { get; internal set; }

        /// <summary>
        /// Contains the object that will be replaced by ObjectDst. This can be useful to process
        /// or test on some old values in this object before it is replaced by ObjectDst.
        /// </summary>
        public object ReplacedDstObject { get; internal set; }

        /// <summary>
        /// The two full links from source to te target property (from root object)
        /// </summary>
        public IPathLink PathLink { get; internal set; }

        /// <summary>
        /// List of excluded nodes. Can be used to ignore some parts of the object.
        /// </summary>
        public List<IPathLink> ExcludedNodes { get; internal set; }

        /// <summary>
        /// Manager used to process the node. Can be used to call some submappings.
        /// Use with caution.
        /// </summary>
        public IManager Manager { get; internal set; }

        /// <summary>
        /// The top source object given to the mapper. For submappings (if defined),
        /// this will be the root of submappings, not the inital root.
        /// </summary>
        public object TopSourceObject { get; internal set; }

        /// <summary>
        /// The top target object (if any), given to the mapper. For submappings (if defined),
        /// this will be the root of submappings, not the inital root.
        /// </summary>
        public object TopTargetObject { get; internal set; }

        /// <summary>
        /// The cache used when call NewIntance(true). It contains the instance created by
        /// source object reference. It is used by engine to relink reference, and, for Converter,
        /// this can be used to have specila behavior.
        /// Altering it may lead to strange results. Use with caution.
        /// </summary>
        public IDictionary<object, object> ObjectsCache { get; internal set; }
    }
}
